#include "Engine/StdAfx.h"
#include <Engine/Foundation/Keyboard.h>
#include <Engine/GlobalEnv.h>
#include <Engine/IEngine.h>

namespace fastbird
{

	Keyboard::Keyboard()
		:mValid(true)
	{
		memset(mKeyDown, 0, sizeof(mKeyDown));
		memset(mKeyPressed, 0, sizeof(mKeyPressed));
	}

	void Keyboard::PushEvent(const KeyboardEvent& keyboardEvent)
	{
		/*IEngine::Log("MakeCode = %d, Flags = %x, VKey = %d, Message = %d, ExtraInformation = %d",
			keyboardEvent.MakeCode, keyboardEvent.Flags, keyboardEvent.VKey, keyboardEvent.Message, keyboardEvent.ExtraInformation);*/

		if (keyboardEvent.Flags & 1) // key up
		{
			mKeyDown[keyboardEvent.VKey] = false;
			mKeyPressed[keyboardEvent.VKey] = true;

			if ( IsPairedKey(keyboardEvent.VKey) )
			{
				unsigned short index = TranslateIndex(keyboardEvent);
				mKeyDown[index] = false;
				mKeyPressed[index] = true;
			}
		}
		else // key down
		{
			mKeyDown[keyboardEvent.VKey] = true;
			if ( IsPairedKey(keyboardEvent.VKey) )
			{
				unsigned short index = TranslateIndex(keyboardEvent);
				mKeyDown[index] = true;
			}
		}
	}

	void Keyboard::EndFrame()
	{
		memset(mKeyPressed, 0, sizeof(mKeyPressed));
	}

	bool Keyboard::IsValid() const
	{
		return mValid;
	}

	void Keyboard::Invalid()
	{
		mValid = true;
	}

	bool Keyboard::IsKeyDown(unsigned short keycode) const
	{
		return mKeyDown[keycode];
	}

	bool Keyboard::IsKeyPressed(unsigned short keycode) const
	{
		return mKeyPressed[keycode];
	}

	bool Keyboard::IsPairedKey(unsigned short keycode) const
	{
		return keycode == VK_SHIFT || keycode == VK_CONTROL || keycode == VK_MENU;
	}

	unsigned short Keyboard::TranslateIndex(const KeyboardEvent& keyboardEvent) const
	{
		assert(IsPairedKey(keyboardEvent.VKey));
		
		int offset = 0;
		if (keyboardEvent.Flags & KEYBOARD_FLAG_KEY_E1)
		{
			offset = 1;
		}
		
		switch(keyboardEvent.VKey)
		{
		case VK_SHIFT:
			{
				return VK_LSHIFT + offset;
			}
			break;

		case VK_CONTROL:
			{
				return VK_LCONTROL + offset;
			}
			break;

		case VK_MENU:
			{
				return VK_LMENU + offset;
			}
			break;

		default:
			{
				assert(0 && "Not defined pair key!");
				return 0;
			}

		}


	}

}